home *** CD-ROM | disk | FTP | other *** search
- /*/ Metrowerks Standard Library Version 1.2 07-May-96 /*/
-
- /*
- * string.c
- *
- * Copyright © 1995-1996 Metrowerks, Inc.
- * All rights reserved.
- *
- * Routines
- * --------
- * strlen
- *
- * strcpy
- * strcat
- * strcmp
- *
- * strncpy
- * strncat
- * strncmp
- *
- * strcoll
- * strxfrm
- *
- * strchr
- * strrchr
- * strstr
- *
- * strspn
- * strcspn
- * strpbrk
- * strtok
- *
- * strerror
- *
- * Modification History
- * --------------------
- *
- * 24-May-95 JFH First code release.
- * 23-Jun-95 JFH Fixed strstr's tendency to not find patterns that aren't
- * suffixes of the target string. Dumb mistake.
- * 29-Nov-95 JFH Tweaked strncpy, strcmp, and strncmp for efficiency.
- * 08-Dec-95 JFH Fixed bug in PPC version of strpbrk (returned p-1 instead of p).
- * 08-Dec-95 JFH Fixed bug in PPC version of strrchr (was copy of PPC version of strchr).
- * 22-Jan-96 JFH Bracketed strlen() and strcpy() by #if <condition too complex to put here>
- * (they are inlined in <string.h> if this condition fails).
- * 29-Apr-96 JFH Merged Win32 changes in.
- * CTV
- */
-
- #include <errno.h>
- #include <stdio.h>
- #include <string.h>
-
- #pragma warn_possunwant off
-
- #if __dest_os == __Win32_os
-
- #include <string.win32.h>
-
- #elif !__MC68K__ || _No_String_Inlines || !defined(__cplusplus)
-
- size_t (strlen)(const char * str)
- {
- size_t len = -1;
-
- #if !__POWERPC__
-
- do
- len++;
- while (*str++);
-
- #else
-
- unsigned char * p = (unsigned char *) str - 1;
-
- do
- len++;
- while (*++p);
-
- #endif
-
- return(len);
- }
-
- char * (strcpy)(char * dst, const char * src)
- {
- #if !__POWERPC__
-
- const char * p = src;
- char * q = dst;
-
- while (*q++ = *p++);
-
- #else
-
- const unsigned char * p = (unsigned char *) src - 1;
- unsigned char * q = (unsigned char *) dst - 1;
-
- while (*++q = *++p);
-
- #endif
-
- return(dst);
- }
-
- #endif /* !__MC68K__ || _No_String_Inlines || !defined(__cplusplus) */
-
- #if __dest_os != __Win32_os
-
- char * strncpy(char * dst, const char * src, size_t n)
- {
- #if !__POWERPC__
-
- const char * p = src;
- char * q = dst;
-
- n++;
-
- while (--n)
- if (!(*q++ = *p++))
- {
- while (--n)
- *q++ = 0;
- break;
- }
-
- #else
-
- const unsigned char * p = (const unsigned char *) src - 1;
- unsigned char * q = (unsigned char *) dst - 1;
- unsigned char zero = 0;
-
- n++;
-
- while (--n)
- if (!(*++q = *++p))
- {
- while (--n)
- *++q = 0;
- break;
- }
-
- #endif
-
- return(dst);
- }
-
- char * strcat(char * dst, const char * src)
- {
- #if !__POWERPC__
-
- const char * p = src;
- char * q = dst;
-
- while (*q++);
-
- q--;
-
- while (*q++ = *p++);
-
- #else
-
- const unsigned char * p = (unsigned char *) src - 1;
- unsigned char * q = (unsigned char *) dst - 1;
-
- while (*++q);
-
- q--;
-
- while (*++q = *++p);
-
- #endif
-
- return(dst);
- }
-
- char * strncat(char * dst, const char * src, size_t n)
- {
- #if !__POWERPC__
-
- const char * p = src;
- char * q = dst;
-
- while (*q++);
-
- q--; n++;
-
- while (--n)
- if (!(*q++ = *p++))
- {
- q--;
- break;
- }
-
- *q = 0;
-
- #else
-
- const unsigned char * p = (unsigned char *) src - 1;
- unsigned char * q = (unsigned char *) dst - 1;
-
- while (*++q);
-
- q--; n++;
-
- while (--n)
- if (!(*++q = *++p))
- {
- q--;
- break;
- }
-
- *++q = 0;
-
- #endif
-
- return(dst);
- }
-
- int strcmp(const char * str1, const char * str2)
- {
- #if !__POWERPC__
-
- const unsigned char * p1 = (unsigned char *) str1;
- const unsigned char * p2 = (unsigned char *) str2;
- unsigned char c1, c2;
-
- while ((c1 = *p1++) == (c2 = *p2++))
- if (!c1)
- return(0);
-
- #else
-
- const unsigned char * p1 = (unsigned char *) str1 - 1;
- const unsigned char * p2 = (unsigned char *) str2 - 1;
- unsigned long c1, c2;
-
- while ((c1 = *++p1) == (c2 = *++p2))
- if (!c1)
- return(0);
-
- #endif
-
- return(c1 - c2);
- }
-
- int strncmp(const char * str1, const char * str2, size_t n)
- {
- #if !__POWERPC__
-
- const unsigned char * p1 = (unsigned char *) str1;
- const unsigned char * p2 = (unsigned char *) str2;
- unsigned char c1, c2;
-
- n++;
-
- while (--n)
- if ((c1 = *p1++) != (c2 = *p2++))
- return(c1 - c2);
- else if (!c1)
- break;
-
- #else
-
- const unsigned char * p1 = (unsigned char *) str1 - 1;
- const unsigned char * p2 = (unsigned char *) str2 - 1;
- unsigned long c1, c2;
-
- n++;
-
- while (--n)
- if ((c1 = *++p1) != (c2 = *++p2))
- return(c1 - c2);
- else if (!c1)
- break;
-
- #endif
-
- return(0);
- }
-
- char * strchr(const char * str, int chr)
- {
- #if !__POWERPC__
-
- const char * p = str;
- char c = chr;
- char ch;
-
- while(ch = *p++)
- if (ch == c)
- return((char *) (p - 1));
-
- return(c ? 0 : (char *) (p - 1));
-
- #else
-
- const unsigned char * p = (unsigned char *) str - 1;
- unsigned long c = chr;
- unsigned long ch;
-
- while(ch = *++p)
- if (ch == c)
- return((char *) p);
-
- return(c ? 0 : (char *) p);
-
- #endif
- }
-
- #endif /* __dest_os != __Win32_os */
-
- int strcoll(const char *str1, const char * str2)
- {
- return(strcmp(str1, str2));
- }
-
- size_t strxfrm(char * str1, const char * str2, size_t n)
- {
- strncpy(str1, str2, n);
- return(strlen(str2));
- }
-
- char * strrchr(const char * str, int chr)
- {
- #if !__POWERPC__
-
- const char * p = str;
- const char * q = 0;
- char c = chr;
- char ch;
-
- while(ch = *p++)
- if (ch == c)
- q = p - 1;
-
- if (q)
- return((char *) q);
-
- return(c ? 0 : (char *) (p - 1));
-
- #else
-
- const unsigned char * p = (unsigned char *) str - 1;
- const unsigned char * q = 0;
- unsigned long c = chr;
- unsigned long ch;
-
- while(ch = *++p)
- if (ch == c)
- q = p;
-
- if (q)
- return((char *) q);
-
- return(c ? 0 : (char *) p);
-
- #endif
- }
-
- typedef unsigned char char_map[32];
-
- #define set_char_map(map, ch) map[ch>>3] |= (1 << (ch&7))
- #define tst_char_map(map, ch) (map[ch>>3] & (1 << (ch&7)))
-
- char * strpbrk(const char * str, const char * set)
- {
- const unsigned char * p;
- int c;
- char_map map = {0};
-
- #if !__POWERPC__
-
- p = (unsigned char *) set;
-
- while (c = *p++)
- set_char_map(map, c);
-
- p = (unsigned char *) str;
-
- while (c = *p++)
- if (tst_char_map(map, c))
- return((char *) (p - 1));
-
- return(NULL);
-
- #else
-
- p = (unsigned char *) set - 1;
-
- while (c = *++p)
- set_char_map(map, c);
-
- p = (unsigned char *) str - 1;
-
- while (c = *++p)
- if (tst_char_map(map, c))
- return((char *) p);
-
- return(NULL);
-
- #endif
- }
-
- size_t strspn(const char * str, const char * set)
- {
- const unsigned char * p;
- int c;
- char_map map = {0};
-
- #if !__POWERPC__
-
- p = (unsigned char *) set;
-
- while (c = *p++)
- set_char_map(map, c);
-
- p = (unsigned char *) str;
-
- while (c = *p++)
- if (!tst_char_map(map, c))
- break;
-
- return(p - (unsigned char *) str - 1);
-
- #else
-
- p = (unsigned char *) set - 1;
-
- while (c = *++p)
- set_char_map(map, c);
-
- p = (unsigned char *) str - 1;
-
- while (c = *++p)
- if (!tst_char_map(map, c))
- break;
-
- return(p - (unsigned char *) str);
-
- #endif
- }
-
- size_t strcspn(const char * str, const char * set)
- {
- const unsigned char * p;
- int c;
- char_map map = {0};
-
- #if !__POWERPC__
-
- p = (unsigned char *) set;
-
- while (c = *p++)
- set_char_map(map, c);
-
- p = (unsigned char *) str;
-
- while (c = *p++)
- if (tst_char_map(map, c))
- break;
-
- return(p - (unsigned char *) str - 1);
-
- #else
-
- p = (unsigned char *) set - 1;
-
- while (c = *++p)
- set_char_map(map, c);
-
- p = (unsigned char *) str - 1;
-
- while (c = *++p)
- if (tst_char_map(map, c))
- break;
-
- return(p - (unsigned char *) str);
-
- #endif
- }
-
- char * strtok(char * str, const char * set)
- {
- unsigned char * p, * q;
- __tls static unsigned char * n = (unsigned char *) "";
- __tls static unsigned char * s = (unsigned char *) "";
- int c;
- char_map map = {0};
-
- if (str)
- s = (unsigned char *) str;
-
- #if !__POWERPC__
-
- p = (unsigned char *) set;
-
- while (c = *p++)
- set_char_map(map, c);
-
- p = s;
-
- while (c = *p++)
- if (!tst_char_map(map, c))
- break;
-
- if (!c)
- {
- s = n;
- return(NULL);
- }
-
- q = p - 1;
-
- while (c = *p++)
- if (tst_char_map(map, c))
- break;
-
- if (!c)
- s = n;
- else
- {
- s = p;
- *--p = 0;
- }
-
- return((char *) q);
-
- #else
-
- p = (unsigned char *) set - 1;
-
- while (c = *++p)
- set_char_map(map, c);
-
- p = s - 1;
-
- while (c = *++p)
- if (!tst_char_map(map, c))
- break;
-
- if (!c)
- {
- s = n;
- return(NULL);
- }
-
- q = p;
-
- while (c = *++p)
- if (tst_char_map(map, c))
- break;
-
- if (!c)
- s = n;
- else
- {
- s = p + 1;
- *p = 0;
- }
-
- return((char *) q);
-
- #endif
- }
-
- char * strstr(const char * str, const char * pat)
- {
- #if !__POWERPC__
-
- unsigned char * s1 = (unsigned char *) str;
- unsigned char * p1 = (unsigned char *) pat;
- unsigned char firstc, c1, c2;
-
- if (!(firstc = *p1++))
- return((char *) s1);
-
- while(c1 = *s1++)
- if (c1 == firstc)
- {
- const unsigned char * s2 = s1;
- const unsigned char * p2 = p1;
-
- while ((c1 = *s2++) == (c2 = *p2++) && c1);
-
- if (!c2)
- return((char *) s1 - 1);
- }
-
- return(NULL);
-
- #else
-
- unsigned char * s1 = (unsigned char *) str-1;
- unsigned char * p1 = (unsigned char *) pat-1;
- unsigned long firstc, c1, c2;
-
- if (!(firstc = *++p1))
- return((char *) s1);
-
- while(c1 = *++s1)
- if (c1 == firstc)
- {
- const unsigned char * s2 = s1-1;
- const unsigned char * p2 = p1-1;
-
- while ((c1 = *++s2) == (c2 = *++p2) && c1);
-
- if (!c2)
- return((char *) s1);
- }
-
- return(NULL);
-
- #endif
- }
-
- #pragma warn_possunwant reset
-